/*
 * GuudCanvas.cpp
 *
 *  Created on: 2013-1-23
 *      Author: heqiu
 */

#include "GuudCanvas.h"

namespace guud {

GuudCanvas::GuudCanvas(uint32_t uiShortUnit, uint32_t uiLongUnit,
		uint32_t uiUnitPixel) {
	m_bShow = true;
	m_bListen = false;
	m_uiShortUnit = uiShortUnit;
	m_uiLongUnit = uiLongUnit;
	m_uiUnitPixel = uiUnitPixel;
	getPeak(m_gpAUnit, m_gpBUnit, m_gpCUnit, m_gpDUnit);
}
GuudCanvas::~GuudCanvas() {

}
void GuudCanvas::draw() {

}
void GuudCanvas::init() {

}
void GuudCanvas::handleEvent(GuudEvent &stEvent) {

}
void GuudCanvas::getPeak(GuudPoint & gpAUnit, GuudPoint & gpBUnit,
		GuudPoint & gpCUnit, GuudPoint & gpDUnit) {
	gpAUnit.m_iX = m_uiShortUnit;
	gpAUnit.m_iY = 0;
	gpBUnit.m_iX = m_uiShortUnit + (m_uiLongUnit - m_uiShortUnit) / 2;
	gpBUnit.m_iY = (m_uiLongUnit - m_uiShortUnit) / 2;
	gpCUnit.m_iX = (m_uiLongUnit - m_uiShortUnit) / 2;
	gpCUnit.m_iY = m_uiShortUnit + (m_uiLongUnit - m_uiShortUnit) / 2;
	gpDUnit.m_iX = 0;
	gpDUnit.m_iY = m_uiShortUnit;
}

bool GuudCanvas::bUnitIn(GuudPoint & gpUnit) {
	if (m_gpAUnit.m_iX > m_gpCUnit.m_iX) {
		if (gpUnit.m_iX >= m_gpDUnit.m_iX && gpUnit.m_iX < m_gpCUnit.m_iX) {
			if (gpUnit.m_iY >= m_gpDUnit.m_iY - gpUnit.m_iX
					&& gpUnit.m_iY <= m_gpDUnit.m_iY + gpUnit.m_iX) {
				return true;
			}
		} else if (gpUnit.m_iX >= m_gpCUnit.m_iX
				&& gpUnit.m_iX < m_gpAUnit.m_iX) {
			if (gpUnit.m_iY >= m_gpDUnit.m_iY - gpUnit.m_iX
					&& gpUnit.m_iY <= (int32_t) m_uiLongUnit - gpUnit.m_iX) {
				return true;
			}
		} else if (gpUnit.m_iX >= m_gpAUnit.m_iX
				&& gpUnit.m_iX <= m_gpBUnit.m_iX) {
			if (gpUnit.m_iY >= gpUnit.m_iX - m_gpAUnit.m_iX
					&& gpUnit.m_iY <= (int32_t) m_uiLongUnit - gpUnit.m_iX) {
				return true;
			}
		}
	} else {
		if (gpUnit.m_iX >= m_gpDUnit.m_iX && gpUnit.m_iX < m_gpAUnit.m_iX) {
			if (gpUnit.m_iY >= m_gpDUnit.m_iY - gpUnit.m_iX
					&& gpUnit.m_iY <= m_gpDUnit.m_iY + gpUnit.m_iX) {
				return true;
			}
		} else if (gpUnit.m_iX >= m_gpAUnit.m_iX
				&& gpUnit.m_iX < m_gpCUnit.m_iX) {
			if (gpUnit.m_iY >= gpUnit.m_iX - m_gpDUnit.m_iY
					&& gpUnit.m_iY <= gpUnit.m_iX + m_gpDUnit.m_iY) {
				return true;
			}
		} else if (gpUnit.m_iX >= m_gpCUnit.m_iX
				&& gpUnit.m_iX <= m_gpBUnit.m_iX) {
			if (gpUnit.m_iY >= gpUnit.m_iX - m_gpAUnit.m_iX
					&& gpUnit.m_iY <= (int32_t) m_uiLongUnit - gpUnit.m_iX) {
				return true;
			}
		}
	}
	return false;
}

void GuudCanvas::cycleAll(void (*func)(int32_t, int32_t, void *),
		void * pData) {
	uint32_t uiBegin = 0;
	for (uint32_t uiLen = m_uiShortUnit; uiLen <= m_uiLongUnit; uiLen++) {
		for (uint32_t ui = (uiBegin + 1) / 2; ui <= m_uiShortUnit + uiBegin / 2;
				ui++) {
			uint32_t ui2 = uiLen - ui;
			func(ui, ui2, pData);
		}
		uiBegin++;
	}
}

void GuudCanvas::cycleRect(GuudRect & rect,
		void (*func)(GuudPoint & gpUnit, GuudPoint & gpScreen, void *),
		void * pData) {
	int32_t iX = getScreenX(rect.x);
	int32_t iY = getScreenY(rect.y);
	uint32_t iW = getScreenWidth(rect.w);
	uint32_t iH = getScreenHeight(rect.h);
	GuudPoint gp1;
	gp1.m_iX = iX;
	gp1.m_iY = iY;
	GuudPoint gp2;
	transformToUnit(gp1, gp2);
	transformToScreen(gp2, gp1);
	iX = gp1.m_iX;
	iY = gp1.m_iY;
	int32_t iTmp = 1;
	for (int32_t j = 0; j < (int32_t) (iH + 4); j += 2) {
		iTmp = 1 - iTmp;
		for (int32_t i = -2; i < (int32_t) (iW + 2); i += 2) {
			GuudPoint gpScreen;
			gpScreen.m_iX = iX + i + iTmp;
			gpScreen.m_iY = iY + j;
			GuudPoint gpUnit;
			transformToUnit(gpScreen, gpUnit);
			if (bUnitIn(gpUnit)) {
				//printf("screen(%d,%d)->unit(%d,%d)\n", gpScreen.m_iX,gpScreen.m_iY, gpUnit.m_iX, gpUnit.m_iY);
				func(gpUnit, gpScreen, pData);
			}
		}
	}
}

void GuudCanvas::transformToScreen(GuudPoint gpUnit, GuudPoint & gpScreen) {
	gpScreen.m_iX = (gpUnit.m_iX - gpUnit.m_iY + m_uiShortUnit);
	gpScreen.m_iY = (gpUnit.m_iX + gpUnit.m_iY - m_uiShortUnit) * 2;
}
void GuudCanvas::transformToScreen(GuudFPoint gpUnit, GuudFPoint & gpScreen) {
	gpScreen.m_fX = (gpUnit.m_fX - gpUnit.m_fY + m_uiShortUnit);
	gpScreen.m_fY = (gpUnit.m_fX + gpUnit.m_fY - m_uiShortUnit) * 2;
}

void GuudCanvas::transformPixelToUnit(GuudPoint gpPixel, GuudPoint & gpUnit) {
	gpUnit.m_iX = (gpPixel.m_iX / 2 + gpPixel.m_iY) / 2 / m_uiUnitPixel;
	gpUnit.m_iY = (gpPixel.m_iY - gpPixel.m_iX / 2
			+ 2 * m_uiShortUnit * m_uiUnitPixel) / 2 / m_uiUnitPixel;
}
void GuudCanvas::transformUnitToPixel(GuudPoint gpUnit, GuudPoint & gpPixel) {
	gpPixel.m_iX = (gpUnit.m_iX - gpUnit.m_iY + m_uiShortUnit) * m_uiUnitPixel
			* 2;
	gpPixel.m_iY = (gpUnit.m_iX + gpUnit.m_iY - m_uiShortUnit) * m_uiUnitPixel;
}
void GuudCanvas::transformToUnit(GuudPoint gpScreen, GuudPoint & gpUnit) {
	gpUnit.m_iX = (gpScreen.m_iX + gpScreen.m_iY / 2) / 2;
	gpUnit.m_iY = (gpScreen.m_iY / 2 - gpScreen.m_iX + 2 * m_uiShortUnit) / 2;
}
void GuudCanvas::transformToUnit(GuudFPoint gpScreen, GuudFPoint & gpUnit) {
	gpUnit.m_fX = (gpScreen.m_fX + gpScreen.m_fY / 2) / 2;
	gpUnit.m_fY = (gpScreen.m_fY / 2 - gpScreen.m_fX + 2 * m_uiShortUnit) / 2;
}

int32_t GuudCanvas::getScreenX(int32_t iXPixel) {
	if (iXPixel >= 0) {
		return iXPixel / m_uiUnitPixel / 2;
	} else {
		return -((-iXPixel) / m_uiUnitPixel / 2) - 1;
	}
}
int32_t GuudCanvas::getScreenY(int32_t iYPixel) {
	if (iYPixel >= 0) {
		return iYPixel * 2 / m_uiUnitPixel;
	} else {
		return -((-iYPixel * 2) / m_uiUnitPixel) - 1;
	}
}
uint32_t GuudCanvas::getScreenWidth(uint32_t uiX) {
	return uiX / m_uiUnitPixel / 2;
}
uint32_t GuudCanvas::getScreenHeight(uint32_t uiY) {
	return uiY * 2 / m_uiUnitPixel;
}

}
